﻿//=====================================================================================================
// LocalizationLibrary
// The Localization Library is a collection of reusable software components that provide 
// support for localization. This library enables you to localize WPF, Silverlight and WP7 applications.
// (http://localizationlibrary.codeplex.com)
//=====================================================================================================
// Author: Nicola Gallo (Website: www.nicola.gallo.name, Email: nicolagmt@hotmail.it) 
//=====================================================================================================

namespace LocalizationLibrary.Tests.Features
{
    //.NET References
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    
    //Microsoft References
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    //LocalizationLibrary References
    using LocalizationLibrary;
    using LocalizationLibrary.Tests.Infrastructure;

    [TestClass]
    public class GenericLocalizationTest
    {
        [TestMethod]
        public void DynamicResourcePartTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context.
                llContext.Reset();

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("it", true));
                    llContext.SetValue("en", "nameDPAKey".Localize("en", true));
                    llContext.SetValue("fr", "nameDPAKey".Localize("fr", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("it"), "Nome");
                Assert.AreEqual(llContext.GetValue<String>("en"), "Name");
                Assert.AreEqual(llContext.GetValue<String>("fr"), "nameDPAKey[fr]");
            }
        }

        [TestMethod]
        public void DynamicResourcePartWithOverrideTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context.
                llContext.Reset();

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                //Registers DeploymentPackB.
                {
                    Assembly assembly = typeof(DeployPackB.Tests.DeployPackBClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }
                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("it", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("it"), "Il mio nome");

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("it", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("it"), "Il mio nome");
            }
        }

        [TestMethod]
        public void LocalizationModelTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context.
                llContext.Reset();

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                DeployPackA.Tests.LocalizationModels.LocalizationModelA locModelA = 
                    new DeployPackA.Tests.LocalizationModels.LocalizationModelA();
                LocalizationManager.RegisterLocalizationModel(locModelA);
                llContext.WaitForLocalization();
                Assert.AreEqual(locModelA.Name, "Name");

                LocalizationManager.CurrentLanguage = (Language)"it";
                llContext.WaitForLocalization();
                Assert.AreEqual(locModelA.Name, "Questo è il mio nome");

                //Registers DeploymentPackB.
                {
                    Assembly assembly = typeof(DeployPackB.Tests.DeployPackBClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }
                llContext.WaitForLocalization();
                Assert.AreEqual(locModelA.Name, "Il mio nome");
            }
        }

        [TestMethod]
        public void LocalizationModelLanguageChangeStressTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context.
                llContext.Reset();

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                DeployPackA.Tests.LocalizationModels.LocalizationModelA locModelA =
                    new DeployPackA.Tests.LocalizationModels.LocalizationModelA();
                LocalizationManager.RegisterLocalizationModel(locModelA);
                bool reverse = false;
                Language[] languages = (Language[])Languages.AvailableLanguages.Clone();
                Language[] revLanguages = (Language[])Languages.AvailableLanguages.Clone();
                Array.Reverse(revLanguages);
                for (int i = 0; i < 100; i++)
                {
                    llContext.Start((_context) =>
                    {
                        Language[] tmpLanguages = (reverse != false) ? languages : revLanguages;
                        reverse = !reverse;
                        foreach (Language language in tmpLanguages)
                        {
                            LocalizationManager.CurrentLanguage = language;
                        }
                    });
                }
                llContext.Join();
                Language tmpLanguage = (Language)"en";
                if (tmpLanguage == null)
                {
                    tmpLanguage = (Language)"en";
                }
                LocalizationManager.CurrentLanguage = tmpLanguage;
                llContext.WaitForLocalization();
                Assert.AreEqual(locModelA.Name, "Name");
            }
        }

        [TestMethod]
        public void LocalizationWithExceptionTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context and assign as LocalizationProvider a new instance of the LocalizationProviderWithExceptionMock type.
                llContext.Reset(typeof(LocalizationProviderWithExceptionMock));

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("fr", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("fr"), null);
            }
        }

        [TestMethod]
        public void SringExtensionTest()
        {
            using (LocalizationLibraryContext llContext = new LocalizationLibraryContext(true))
            {
                //Resets current context.
                llContext.Reset();

                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("it", true));
                    llContext.SetValue("en", "nameDPAKey".Localize("fr", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("it"), null);
                Assert.AreEqual(llContext.GetValue<String>("fr"), null);

                //Registers DeploymentPackA.
                {
                    Assembly assembly = typeof(DeployPackA.Tests.DeployPackAClass).Assembly;
                    LocalizationManager.RegisterAssembly(assembly);
                }

                llContext.Start((_context) =>
                {
                    llContext.SetValue("it", "nameDPAKey".Localize("it", true));
                    llContext.SetValue("fr", "nameDPAKey".Localize("fr", true));
                });
                llContext.Join();

                Assert.AreEqual(llContext.GetValue<String>("it"), "Nome");
                Assert.AreEqual(llContext.GetValue<String>("fr"), "nameDPAKey[fr]");
            }
        }
    }
}